﻿namespace Wiki.Security.Cryptography
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;
    using System.Net;
    using System.Security.Cryptography;
    using System.Text;

    public static class MD5Digest
    {
        public static string Calculate(string content)
        {
            if (null == content)
            {
                throw new ArgumentNullException("content");
            }

            return Calculate(content, UTF8Encoding.Default);
        }

        public static string Calculate(string content, Encoding encoding)
        {
            if (null == content)
            {
                throw new ArgumentNullException("content");
            }

            if (null == encoding)
            {
                throw new ArgumentNullException("encoding");
            }

            return Calculate(encoding.GetBytes(content));
        }

        public static string Calculate(FileSystemInfo file)
        {
            if (null == file)
            {
                throw new ArgumentNullException("file");
            }

            string value = null;

            using (Stream stream = File.Open(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                value = Calculate(stream);
            }

            return value;
        }

        public static string Calculate(Uri resource)
        {
            if (null == resource)
            {
                throw new ArgumentNullException("resource");
            }

            string value = null;

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource);

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                value = Calculate(response.GetResponseStream());
            }

            return value;
        }

        public static string Calculate(Stream content)
        {
            if (null == content)
            {
                throw new ArgumentNullException("content");
            }

            string value = null;
            using (StreamReader reader = new StreamReader(content))
            {
                using (MD5 md5 = new MD5CryptoServiceProvider())
                {
                    byte[] hash = md5.ComputeHash(content);
                    value = Convert.ToBase64String(hash);
                }
            }

            return value;
        }

        public static string Calculate(byte[] content)
        {
            if (null == content)
            {
                throw new ArgumentNullException("content");
            }

            string value = null;
            using (MD5 md5 = new MD5CryptoServiceProvider())
            {
                byte[] hash = md5.ComputeHash(content);
                value = Convert.ToBase64String(hash);
            }

            return value;
        }
    }
}